package com.apache.portal.common.util;

import com.apache.portal.weixin.core.manager.MyX509TrustManager;
import com.apache.tools.StrUtil;
import com.apache.uct.common.ToolsUtil;
import net.sf.json.JSONObject;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.*;
import java.net.ConnectException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

public class HttpRequestTools {

    private static HttpRequestTools instance;

    private HttpRequestTools() {
    }

    public static HttpRequestTools getInstance() {
        if (null == instance) {
            instance = new HttpRequestTools();
        }
        return instance;
    }

    /**
     * 发起https请求并获取结果
     *
     * @param requestUrl 请求地址
     * @param requestMethod 请求方式（GET、POST）
     * @param outputStr 提交的数据
     */
    public Object httpRequest(String requestUrl, String requestMethod, String outputStr,
            Map<String, String> params) {
        String resultType = StrUtil.doNull(params.get("resultType"), "json");
        try {
            // 创建SSLContext对象，并使用我们指定的信任管理器初始化
            TrustManager[] tm = { new MyX509TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();

            URL url = new URL(requestUrl);
            HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
            httpUrlConn.setSSLSocketFactory(ssf);

            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);
            // 设置请求方式（GET/POST）
            httpUrlConn.setRequestMethod(requestMethod);

            if ("GET".equalsIgnoreCase(requestMethod))
                httpUrlConn.connect();

            // 当有数据需要提交时
            if (null != outputStr) {
                OutputStream outputStream = httpUrlConn.getOutputStream();
                // 注意编码格式，防止中文乱码
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }
            Object obj = null;
            InputStream inputStream = httpUrlConn.getInputStream();
            if ("json".equalsIgnoreCase(resultType)) {
                obj = getInfoForJson(inputStream);
            } else if ("pic".equalsIgnoreCase(resultType)) {
                String contentType = httpUrlConn.getContentType();
                String contentDisposition = httpUrlConn.getHeaderField("Content-Disposition");
                if (StrUtil.isNull(contentDisposition))
                    return null;
                obj = getFileForPic(contentType, contentDisposition, params.get("openId"),
                        inputStream);
            }
            // 释放资源
            inputStream.close();
            inputStream = null;
            httpUrlConn.disconnect();
        } catch (ConnectException ce) {
            //log.error("Weixin server connection timed out.");
        } catch (Exception e) {
            //log.error("https request error:{}", e);
        }
        return null;
    }

    private JSONObject getInfoForJson(InputStream inputStream) throws Exception {
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        StringBuffer buffer = new StringBuffer();
        String str = null;
        while ((str = bufferedReader.readLine()) != null) {
            buffer.append(str);
        }
        bufferedReader.close();
        inputStreamReader.close();
        JSONObject jsonObject = JSONObject.fromObject(buffer.toString());
        return jsonObject;
    }

    private Map<String, String> getFileForPic(String contentType, String contentDisposition,
            String openId, InputStream inputStream) throws Exception {
        Map<String, String> result = new HashMap<String, String>();
        String mediaFilePath = ToolsUtil.getInstance().getValueByKey("media_file_path");
        String ss[] = contentDisposition.split("filename=");
        //	String contentDisposition = httpUrlConn.getHeaderField("Content-Disposition");
        String[] t = contentType.split("/");
        String type = t[0];
        String nameEx = "." + t[1];
        String fileName = ss[1].substring(1, ss[1].length() - 1);//DateUtils.Now.toLong() + nameEx;
        String floderName = type + "/" + openId + "/";
        String cacDir = mediaFilePath + floderName;
        File dir = new File(cacDir);
        if (!dir.exists()) {
            dir.mkdirs();
        }

        result.put("nameEx", nameEx);//后缀
        result.put("fileName", fileName);//文件名
        result.put("filePath", cacDir + fileName);//路径
        result.put("floderName",
                ToolsUtil.getInstance().getValueByKey("web_http") + "/portal/upload/" + floderName
                        + fileName);
        int BUFFER_SIZE = 4096;
        byte[] data = new byte[BUFFER_SIZE];
        int count = -1;
        FileOutputStream fs = null;
        try {
            fs = new FileOutputStream(cacDir + fileName);
            while ((count = inputStream.read(data, 0, BUFFER_SIZE)) != -1) {
                fs.write(data, 0, count);
            }
            fs.flush();
        } finally {
            IOUtils.closeQuietly(fs);
        }
        return result;
    }

    /**
     * 根据URL获得所有的html信息
     *
     * @param url
     * @return
     */
    public String getHttpClientHtml(String url, String code) {
        String html = null;
        HttpClient httpClient = new DefaultHttpClient();// 创建httpClient对象
        HttpGet httpget = new HttpGet(url);// 以get方式请求该URL
        try {
            HttpResponse responce = httpClient.execute(httpget);// 得到responce对象
            int resStatu = responce.getStatusLine().getStatusCode();// 返回码
            if (resStatu == HttpStatus.SC_OK) {// 200正常 其他就不对
                // 获得相应实体
                HttpEntity entity = responce.getEntity();
                if (entity != null) {
                    html = new String(EntityUtils.toString(entity).getBytes("ISO-8859-1"),
                            code);// 获得html源代码
                }
            }
        } catch (Exception e) {
            System.out.println("访问【" + url + "】出现异常!");
            e.printStackTrace();
        } finally {
            httpClient.getConnectionManager().shutdown();
        }
        return html;
    }

    /**
     * 默认编码获取HTML代码
     *
     * @param url
     * @return
     */
    public String getHttpClientHtml(String url) {
        String html = null;
        HttpClient httpClient = new DefaultHttpClient();// 创建httpClient对象
        HttpGet httpget = new HttpGet(url);// 以get方式请求该URL
        try {
            HttpResponse responce = httpClient.execute(httpget);// 得到responce对象
            int resStatu = responce.getStatusLine().getStatusCode();// 返回码
            if (resStatu == HttpStatus.SC_OK) {// 200正常 其他就不对
                // 获得相应实体
                HttpEntity entity = responce.getEntity();
                if (entity != null) {
                    html = EntityUtils.toString(entity);// 获得html源代码
                }
            }
        } catch (Exception e) {
            System.out.println("访问【" + url + "】出现异常!");
            e.printStackTrace();
        } finally {
            httpClient.getConnectionManager().shutdown();
        }
        return html;
    }
}
